package org.abc.fund.service.dataSource;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class JqAuthService {

    private final ObjectMapper objectMapper;

    /**
     * Conda 虚拟环境中的 Python 解释器路径
     * 例如：
     * F:/miniconda3/envs/fundcollection/python.exe
     */
    @Value("${data.collection.python.interpreter.path:python3}")
    private String condaPythonPath;

    public Map<String, Object> checkAccount(String account, String password) {
        try {
            // 1. 找到脚本
            String scriptPath =
                    getClass().getClassLoader().getResource("scripts/checkAccount.py").getPath();

            if (System.getProperty("os.name").toLowerCase().contains("win")) {
                scriptPath = scriptPath.substring(1); // windows path fix
            }

            log.info("使用的Python解释器：{}", condaPythonPath);
            log.info("使用的认证脚本路径：{}", scriptPath);

            // 2. 传给 Python 的 JSON 参数
            Map<String, Object> scriptArgs = Map.of(
                    "account", account,
                    "password", password
            );
            String argsJson = objectMapper.writeValueAsString(scriptArgs);

            // 3. 构建进程
            ProcessBuilder pb = new ProcessBuilder(condaPythonPath, scriptPath);
            pb.environment().put("PYTHONUTF8", "1");
            pb.environment().put("PYTHONIOENCODING", "UTF-8");

            log.info("开始执行聚宽认证脚本");
            log.debug("脚本入参JSON：{}", argsJson);

            Process process = pb.start();

            // ⬅ 写入 JSON 到 Python 标准输入
            try (var writer = new java.io.OutputStreamWriter(
                    process.getOutputStream(), StandardCharsets.UTF_8)) {
                writer.write(argsJson);
                writer.flush();
            }

            // 4. 读取输出
            var stdout = new org.abc.fund.service.tools.StreamGobbler(process.getInputStream());
            var stderr = new org.abc.fund.service.tools.StreamGobbler(process.getErrorStream());
            new Thread(stdout).start();
            new Thread(stderr).start();

            boolean finished = process.waitFor(60, TimeUnit.SECONDS);
            if (!finished) {
                process.destroyForcibly();
                throw new RuntimeException("认证脚本执行超时");
            }

            int exitCode = process.exitValue();
            String output = stdout.getOutput();
            String errorOutput = stderr.getOutput();

            log.info("认证脚本退出码 = {}", exitCode);
            log.debug("认证脚本标准输出 = {}", output);
            log.debug("认证脚本错误输出 = {}", errorOutput);

            // 失败情况
            if (exitCode != 0) {
                throw new RuntimeException("认证脚本返回错误：" + errorOutput);
            }

            if (output == null || output.isEmpty()) {
                throw new RuntimeException("认证脚本未返回任何内容");
            }

            int jsonStartIndex = output.indexOf("{");
            if (jsonStartIndex > 0) {
                log.warn("检测到脚本输出前缀字符，已自动截取：{}", output);
                output = output.substring(jsonStartIndex);
            }

            // 转换为 Map 返回给 Controller
            return objectMapper.readValue(output, Map.class);

        } catch (Exception e) {
            log.error("聚宽账号校验失败", e);
            throw new RuntimeException("聚宽账号校验失败：" + e.getMessage(), e);
        }
    }
}
